/*
 * Copyright 2003-2007 (c) Live Media Pty Ltd. <argot@einet.com.au> 
 *
 * This software is licensed under the Argot Public License 
 * which may be found in the file LICENSE distributed 
 * with this software.
 *
 * More information about this license can be found at
 * http://www.einet.com.au/License
 * 
 * The Developer of this software is Live Media Pty Ltd,
 * PO Box 4591, Melbourne 3001, Australia.  The license is subject 
 * to the law of Victoria, Australia, and subject to exclusive 
 * jurisdiction of the Victorian courts.
 */

package com.colony.transport.socket;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Stack;

import com.argot.network.TypeEndPoint;
import com.colony.transport.Client;

public class SocketClient
implements Client
{
	private static final int MAGIC1 = 10;
	private static final int MAGIC2 = 20;
	
	private int _port;
	private InetAddress _host;
	private Stack _stack;

	public SocketClient( String host, int port ) 
	throws UnknownHostException
	{
		_host = InetAddress.getByName(host);
		_port = port;
		_stack = new Stack();
	}

	public TypeEndPoint openLink()
	throws IOException
	{
		synchronized(_stack)
		{
			if (!_stack.isEmpty())
			{
				SocketEndPoint ep = (SocketEndPoint) _stack.pop();
				if (!ep.getSocket().isClosed())
				{
					ep.getOutputStream().write(MAGIC1);
					ep.getOutputStream().write(MAGIC2);
					return ep;
				}
				System.out.println("socket closed!");
			}
		}
     	Socket socket = new Socket();
     	InetSocketAddress addr = new InetSocketAddress( _host, _port );
     	socket.connect(addr,3000);
		socket.getOutputStream().write(MAGIC1);
		socket.getOutputStream().write(MAGIC2);
		return new SocketEndPoint( socket );		
	}
	
	public void closeLink( TypeEndPoint endPoint )
	{
		synchronized(_stack)
		{
			_stack.push(endPoint);
		}
	}

	private static class SocketEndPoint
	implements TypeEndPoint
	{
		private Socket _socket;
		private InputStream _in;
		private OutputStream _out;
		
		public SocketEndPoint(Socket socket)
		throws IOException
		{
			_socket = socket;
			_in = new BufferedInputStream(socket.getInputStream());
			_out = new BufferedOutputStream(socket.getOutputStream());
		}
		
		public InputStream getInputStream()
		{
			return _in;
		}

		public OutputStream getOutputStream()
		{
			return _out;
		}
		
		public Socket getSocket()
		{
			return _socket;
		}
		
	}
	
}
